﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.IO;
using Krile.Kernel;

namespace Wassrile.Subsystem
{
    /// <summary>
    /// 絵文字マネージャ(単純処理)
    /// </summary>
    public class PictogramResolver
    {
        const string PictogramExt = ".gif";
        private object cacheLocker = new object();
        Dictionary<string, PictoImage> resolvCache = new Dictionary<string, PictoImage>();
        class PictoImage
        {
            const int auto_dispose_count = 60000;

            Image internal_cache = null;
            System.Threading.Timer timer = null;
            public PictoImage(Image img)
            {
                SetImage(img);
            }

            private void TimerInit()
            {
                if (timer != null)
                    timer.Dispose();
                timer = new System.Threading.Timer(
                    new System.Threading.TimerCallback(TCallback),
                    null,
                    auto_dispose_count, System.Threading.Timeout.Infinite);
            }

            public Image GetImage()
            {
                TimerInit();
                return internal_cache;
            }

            public void SetImage(Image img)
            {
                internal_cache = img;
                TimerInit();
            }

            private void TCallback(object o)
            {
                timer.Dispose();
                timer = null;
                internal_cache.Dispose();
                internal_cache = null;
            }
        }

        public Image GetPictogram(string code)
        {
            lock (cacheLocker)
            {
                if (!resolvCache.ContainsKey(code))
                {
                    var path = BuildPath(code);
                    if (File.Exists(path))
                        resolvCache.Add(code, new PictoImage(Image.FromFile(path)));
                    else
                        resolvCache.Add(code, new PictoImage(Properties.Resources.unavailable));
                }
                else if (resolvCache[code].GetImage() == null)
                {
                    var path = BuildPath(code);
                    if (File.Exists(path))
                        resolvCache[code].SetImage(Image.FromFile(path));
                    else
                        resolvCache[code].SetImage(Properties.Resources.unavailable);
                }
                return resolvCache[code].GetImage();
            }
        }

        private string BuildPath(string code)
        {
            string path = Path.Combine(Bridge.Config.PluginPath, Define.PictogramDir);
            return Path.Combine(path, code + PictogramExt);
        }

        public IEnumerable<string> GetCodeCandidates()
        {
            for (uint i = 0xE000; i <= 0xFFFF; i++)
            {
                if (File.Exists(BuildPath(i.ToString("X"))))
                {
                    yield return i.ToString("X");
                }
            }
        }
    }
}